/*
 * This files defines common objects across the simulation. 
 * 
 * In order to make things as simple as possible, we use few data
 * structures that contain much of the simulation parameters.
 * 
 */
 
  #include <stdio.h>
  #include <stdlib.h>
  #include <math.h>
  
  #include <common.h> 
 
  int allocate_arrays( SIM_DATA *s ) {
	  
    s->X      = (double *)malloc( sizeof(double)*4 * s->N );
    s->X_p    = (double *)malloc( sizeof(double)*4 * s->N );
    s->XDOT   = (double *)malloc( sizeof(double)*4 * s->N );
    s->XDOT_p = (double *)malloc( sizeof(double)*4 * s->N );
    s->F      = (double *)malloc( sizeof(double)*4 * s->N );
    s->FDOT   = (double *)malloc( sizeof(double)*4 * s->N );
    s->D2     = (double *)malloc( sizeof(double)*4 * s->N );
    s->D3     = (double *)malloc( sizeof(double)*4 * s->N );

    s->T0    = (double *)malloc( sizeof(double) * s->N );
    s->STEP  = (double *)malloc( sizeof(double) * s->N );

    s->NEXT  = (int    *)malloc( sizeof(int)    * s->N );
	  
    return 0;
  }
  
  int check_simulation_params( SIM_DATA* s ) {
	
	if( s->N_active + s->N_ghosts != s->N ) {
		fprintf( stderr, "ERROR: N_active + N_ghosts must match N_total. ABORTING.\n" );
		return -5;
	}
	  
	if( s->X  == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
    
	if( s->X_p == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	
	if( s->XDOT == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	if( s->XDOT_p == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}

	if( s->F == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	
	if( s->FDOT == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
    
    if( s->D2 == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	
	if( s->D3 == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	
	if( s->T0 == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}

	if( s->STEP== NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	
	if( s->NEXT == NULL ) {
	  fprintf( stderr, "ERROR ALLOCATING ARRAYS. ABORTING.\n" );
	  return -10;
	}
	
	fprintf( stderr, "#SIMULATION PARAMETERS ARE OK.\n" );
	
	return 0; 
  }
  
  int dump_phasecoordinates( FILE* stream, SIM_DATA* s ) {
	  
    int i,k;
    if( stream == NULL ) {
        fprintf( stderr, "ERROR. CANNOT WRITE PHASE COORDINATES TO FILE. ABORTING.\n" );
      return -3;
    }
    
    //fprintf( stream, "#%6s %12s %12s %12s %15s %13s %13s\n", "MASS", "x", "y", "z", "vx", "vy", "vz" );
    
    for( i=0; i< s->N; i++ ) {
      
      fprintf( stream, "%4.5lf", s->X[4*i + 3] );
      
      for( k=0; k<3; k++ )
        fprintf( stream, "%14.5lf", s->X[4*i + k] );
        
      for( k=0; k<3; k++ )
        fprintf( stream, "%14.5lf", s->XDOT[4*i + k] );
      
      fprintf( stream, "\n" );
    } 
	  
	  
    return 0;
  }
